import random
import sys
import pygame

# 游戏窗口宽度
window_width = 600
# 游戏窗口高度
window_height = 600
# rect 大小
pixel = 10
# 走速
tick = 15


# 蛇类
class Snake:
    # 初始化
    def __init__(self, dest=(0, 90)):
        self.dir = pygame.K_d
        self.body = []
        self.dest = dest
        for x in range(5):
            self.add_rect()

    # 增加蛇长度
    def add_rect(self):
        left, top = self.dest
        if self.body:
            left, top = (self.body[0].left, self.body[0].top)
        rect = pygame.Rect(left, top, pixel, pixel)
        # pygame.Rect(0, 0, 25, 255)
        if self.dir == pygame.K_a:
            rect.left -= pixel
        elif self.dir == pygame.K_d:
            rect.left += pixel
        elif self.dir == pygame.K_w:
            rect.top -= pixel
        elif self.dir == pygame.K_s:
            rect.top += pixel
        self.body.insert(0, rect)

    # 删除最后一个接点
    def del_last_rect(self):
        self.body.pop()

    # 移动
    def move(self):
        self.add_rect()
        self.del_last_rect()

    # 自动移动
    def auto_move(self):
        # 按制定的概率修改蛇的方向
        if random.randint(0, 200) in range(0, 20):
            if self.dir == pygame.K_d:
                self.dir = pygame.K_s
            elif self.dir == pygame.K_s:
                self.dir = pygame.K_a
            elif self.dir == pygame.K_a:
                self.dir = pygame.K_w
            else:
                self.dir = pygame.K_d
        # 保证电脑蛇在可移动区域内
        if self.body[0].x not in range(window_width):
            self.dir = pygame.K_a if self.dir == pygame.K_d else pygame.K_d
        if self.body[0].y not in range(window_height):
            self.dir = pygame.K_w if self.dir == pygame.K_s else pygame.K_s
        # 移动
        self.move()

    # 改变方向
    def change_dir(self, key):
        # 存在一个bug 限制不能原地掉头
        if key in [pygame.K_a, pygame.K_w, pygame.K_d, pygame.K_s]:
            self.dir = key

    # 蛇的生命状态
    def is_die(self):
        if self.body:
            if self.body[0].x not in range(window_width):
                self.body.clear()
                return True
            if self.body[0].y not in range(window_height):
                self.body.clear()
                return True
        else:
            return True
        return False


# 食物
class Food:
    # 初始化
    def __init__(self):
        self.rect = pygame.Rect(-pixel, 0, pixel, pixel)

    # 删除食物
    def remove(self):
        self.rect.x = -pixel

    # 设置食物刷新位置
    def set(self):
        if self.rect.x == -pixel:
            # 取刷新范围
            all_points = []
            for item in range(pixel, window_width, pixel):
                all_points.append(item)
            self.rect.left = random.choice(all_points)
            self.rect.top = random.choice(all_points)


def main():
    # 初始化
    pygame.init()
    # 设置游戏窗口大小
    screen = pygame.display.set_mode((window_width, window_height))
    # 窗口标题
    pygame.display.set_caption("贪吃蛇")
    # 刷新率
    clock = pygame.time.Clock()
    # 创建蛇对象
    snake = Snake((0, 300))
    snake_other = Snake()
    # 食物创建
    food = Food()
    # 蛇的状态
    is_die = False
    # 蛇的长度
    snake_count = 5
    # 创建背景颜色对象
    bg = pygame.image.load("./bg.jpg")
    # 开始死循环
    while True:
        # 遍历获取所有事件，监听事件
        for event in pygame.event.get():
            # 判断用户是否点击退出按钮
            if event.type == pygame.QUIT:
                # 退出游戏
                pygame.quit()
                # 退出系统
                sys.exit()
            if event.type == pygame.KEYDOWN:
                # 控制蛇方向
                snake.change_dir(event.key)
                # 重新开始游戏
                if event.key == pygame.K_SPACE and is_die:
                    return main()

        # 窗口背景图片
        screen.blit(bg, (0, 0))

        # 画蛇(我的)
        for item in snake.body:
            pygame.draw.rect(screen, (255, 255, 255), item, 0)

        # 画蛇(对方)
        for item in snake_other.body:
            pygame.draw.rect(screen, (200, 200, 0), item, 0)
        snake_other.auto_move()

        # 判断蛇的死亡
        is_die = snake.is_die()
        if not is_die:
            snake.move()
        else:
            show_text(screen, "Game Over", (100, 100), color=(255, 255, 255), size=100)

        # 判断是否吃食物
        if snake.body:
            if food.rect == snake.body[0]:
                snake_count += 1
                snake.add_rect()
                food.remove()

            # 判断是否和电脑蛇碰撞
            if snake.body[0] in snake_other.body:
                # 我的蛇被撞死
                snake.body[0].x = -25

        # 画食
        food.set()
        pygame.draw.rect(screen, (150, 0, 50), food.rect, 0)

        # 显示成绩
        show_text(screen, "SnakeCount:" + str(snake_count), (50, 550), color=(200, 200, 200))

        # 刷新
        pygame.display.flip()

        clock.tick(tick)


# 打印文字
def show_text(screen, text, dest, font="宋体", size=60, color=(0, 0, 0)):
    font = pygame.font.SysFont(font, size)
    text = font.render(text, 1, color)
    screen.blit(text, dest)


if __name__ == '__main__':
    main()
